package org.jeecg.modules.demo.temple.weixin.controller;

import com.alibaba.druid.support.json.JSONUtils;
import com.alibaba.druid.util.StringUtils;
import com.alibaba.druid.util.Utils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.http.HttpUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.gson.JsonObject;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.shiro.codec.Base64;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.common.system.query.QueryGenerator;
import org.jeecg.common.util.RestUtil;
import org.jeecg.config.sign.util.HttpUtils;
import org.jeecg.modules.demo.temple.sys.entity.SysDepart;
import org.jeecg.modules.demo.temple.sys.service.ISysDepart;
import org.jeecg.modules.demo.temple.weixin.entity.TempleUser;
import org.jeecg.modules.demo.temple.weixin.service.ITempleUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import java.security.spec.AlgorithmParameterSpec;

/**
 * @Description: 微信接口服务
 * @Author: jeecg-boot
 * @Date:   2022-04-24
 * @Version: V1.0
 */
@Api(tags="微信接口服务")
@RestController
@RequestMapping("/wechat")
@Slf4j
public class WechatController {

    @Value(value = "${justauth.type.WECHAT_MINI.appId}")
    private String appid;

    @Value(value = "${justauth.type.WECHAT_MINI.appSecret}")
    private String appSecret;

    @Value(value = "${justauth.type.WECHAT_MINI.jscode2sessionUrl}")
    private String jscode2sessionUrl;

    @Autowired
    private ITempleUserService templeUserService;

    @Autowired
    private ISysDepart sysDepartService;

    /**
     *   通过code获取session_key和openid
     *
     * @param  code
     * @return JSONObject
     */
    @AutoLog(value = "通过code获取微信openid")
    @ApiOperation(value="通过code获取微信openid", notes="通过code获取微信openid")
    @GetMapping(value = "/getOpenId")
    public Result<JSONObject> authCode2Session(String code,String sysOrgCode,HttpServletRequest req){
        JSONObject params = new JSONObject();
        SysDepart sysDepart = new SysDepart();
        sysDepart.setOrgCode(sysOrgCode);
        QueryWrapper<SysDepart> queryWrapper = QueryGenerator.initQueryWrapper(sysDepart, req.getParameterMap());
        SysDepart resDepart = sysDepartService.getOne(queryWrapper);
        params.put("appid",resDepart.getWechatMiniAppId());
        params.put("secret",resDepart.getWechatMiniAppSecret());
        params.put("js_code",code);
        params.put("grant_type","authorization_code");
        ResponseEntity<String> res = RestUtil.request(jscode2sessionUrl, HttpMethod.GET,null,params,null, String.class);
        String body = res.getBody();
        JSONObject jsonRes= (JSONObject)JSONObject.parse(body);

        return Result.OK(jsonRes);
    }

    /**
     *   微信登陆
     *
     * @param  templeUser
     * @return JSONObject
     */
    @AutoLog(value = "微信登陆")
    @ApiOperation(value="微信登陆", notes="微信登陆")
    @GetMapping(value = "/wechatLogin")
    public Result<TempleUser> wechatLogin(TempleUser templeUser, HttpServletRequest req){
        TempleUser qryRule = new TempleUser();
        qryRule.setOpenId(templeUser.getOpenId());
        QueryWrapper<TempleUser> queryWrapper = QueryGenerator.initQueryWrapper(qryRule, req.getParameterMap());
        TempleUser user = templeUserService.getOne(queryWrapper);
        if(user==null){
            templeUserService.save(templeUser);
            return Result.OK(templeUser);
        }else{
            if(
                    user.getAvatarUrl()!=templeUser.getAvatarUrl()||
                    user.getNickName()!=templeUser.getNickName()||
                    user.getSex()!=templeUser.getSex()
            ){
                user.setAvatarUrl(templeUser.getAvatarUrl());
                user.setNickName(templeUser.getNickName());
                user.setSex(templeUser.getSex());
                templeUserService.updateById(user);
            }
            return Result.OK(user);
        }
    }


    /**
     *   微信解密手机号
     *
     * @param  id, session_key, encryptedData, iv
     * @return JSONObject
     */
    @AutoLog(value = "微信登陆")
    @ApiOperation(value="微信登陆", notes="微信登陆")
    @GetMapping(value = "/decryptMobile")
    public Result<TempleUser> decryptMobile(String id, String session_key, String encryptedData, String iv, HttpServletRequest req){
        String mobile="";
        byte[] encrypData = Base64.decode(encryptedData);
        byte[] ivData = Base64.decode(iv);
        byte[] sessionKey = Base64.decode(session_key);
        try {
            mobile = decrypt(sessionKey,ivData,encrypData);
            JSONObject json= (JSONObject)JSONObject.parse(mobile);
            mobile = (String)json.get("phoneNumber");
        } catch (Exception e) {
            e.printStackTrace();
            return Result.OK("error:"+e.getMessage(),null);
        }


        TempleUser qryRule = new TempleUser();
        qryRule.setId(id);
        QueryWrapper<TempleUser> queryWrapper = QueryGenerator.initQueryWrapper(qryRule, req.getParameterMap());
        TempleUser user = templeUserService.getOne(queryWrapper);
        user.setMobile(mobile);
        if(user!=null){
            templeUserService.updateById(user);
            return Result.OK(user);
        }else{
            return Result.OK("error:not find user",user);
        }
    }

    public static String decrypt(byte[] key, byte[] iv, byte[] encData) throws Exception {
        AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        SecretKeySpec keySpec = new SecretKeySpec(key, "AES");
        cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
        //解析解密后的字符串
        return new String(cipher.doFinal(encData),"UTF-8");
    }
}
